package com.thinvent.nj.ais.service.impl;

import com.thinvent.nj.common.exception.ServiceException;
import com.thinvent.nj.common.page.Page;
import com.thinvent.nj.common.page.QueryParameter;
import com.thinvent.nj.common.util.CollectionUtil;
import com.thinvent.nj.common.util.MapperUtil;
import com.thinvent.nj.common.util.StringUtil;
import com.thinvent.nj.mybatis.service.impl.BaseCURDServiceImpl;
import com.thinvent.nj.ais.entity.Resource;
import com.thinvent.nj.ais.entity.Role;
import com.thinvent.nj.ais.entity.User;
import com.thinvent.nj.ais.mapper.UserMapper;
import com.thinvent.nj.ais.service.ServerService;
import com.thinvent.nj.ais.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户Service
 * @author liupj
 */
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class UserServiceImpl extends BaseCURDServiceImpl<User, String> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ServerService serverService;


    @CacheEvict(cacheNames = "sys", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveUser(User user) {
        if (user == null) {
            throw new ServiceException("user cannot be null.");
        }

        String userId = user.getId();

        // 新增
        if (userId == null) {
            // 保存用户基本信息
            userMapper.insert(user);
        } else { // 修改
            // 更新用户基本信息
            userMapper.update(user);

            // 删除用户组织关联关系
            userMapper.deleteUserOrgList(userId);
            // 删除用户角色关联关系
            userMapper.deleteUserRoleList(userId);
        }

        // 保存用户组织关联关系
        if (user.getOrgList().size() > 0) {
            userMapper.insertUserOrgList(user.getId(), user.getOrgList());
        }

        // 保存用户角色关联关系
        if (user.getRoleList().size() > 0) {
            userMapper.insertUserRoleList(user.getId(), user.getRoleList());
        }
    }

    @Override
    public void deleteUser(User user) {

    }

    @Cacheable(cacheNames = "sys", keyGenerator = "keyGenerator")
    @Override
    public User findByUsername(String username, String uri) {
        User user = userMapper.findByUsername(username);

        Set<Resource> resources = new HashSet<>();
        Set<Resource> menus = new TreeSet<>((o1, o2) -> o1.getSort() <= o2.getSort() ? -1 : 1);

        for (Role role : user.getRoleList()) {
            resources.addAll(role.getResourceList());
            menus.addAll(role.getResourceList().stream().filter(e -> e.getEnabled().equals(true)).filter(e -> "1".equals(e.getType())).collect(Collectors.toSet()));
        }

        user.setResourceList(new ArrayList<>(resources));

        Map<String, String> serverMap = serverService.getServerMapByUri(uri);

        for (Resource menu : menus) {
            if (StringUtil.isNullOrEmpty(menu.getUri())) {
                continue;
            }

            String prefix = StringUtil.isNullOrEmpty(serverMap.get(menu.getProjectNo())) ? "" : serverMap.get(menu.getProjectNo());
            menu.setUri(prefix + menu.getUri());
        }

        user.setMenus(CollectionUtil.listToTree(MapperUtil.convertToListMap(menus), "id", "pId"));
        return user;
    }

    @Cacheable(cacheNames = "sys", keyGenerator = "keyGenerator")
    @Override
    public List<User> findByOrgId(String orgId) {
        return userMapper.findByOrgId(orgId);
    }

    @Cacheable(cacheNames = "sys", keyGenerator = "keyGenerator")
    @Override
    public List<User> findByRoleId(String roleId) {
        return userMapper.findByRoleId(roleId);
    }

    @Cacheable(cacheNames = "sys", keyGenerator = "keyGenerator")
    @Override
    public User get(String s) {
        return super.get(s);
    }

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "sys", allEntries = true)
    @Override
    public void delete(String s) {
        super.delete(s);
    }

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "sys", allEntries = true)
    @Override
    public void update(User user) {
        super.update(user);
    }

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "sys", allEntries = true)
    @Override
    public void insert(User user) {
        super.insert(user);
    }

    @Cacheable(cacheNames = "sys", keyGenerator = "keyGenerator")
    @Override
    public List<User> findList(Map<String, Object> params) {
        return super.findList(params);
    }

    @Cacheable(cacheNames = "sys", keyGenerator = "keyGenerator")
    @Override
    public Page<User> findPage(QueryParameter queryParameter, Map<String, Object> params) {
        return super.findPage(queryParameter, params);
    }
}
